package chapt03.star;
// Triangle.java
// OpenGL SuperBible
// Demonstrates OpenGL Triangle Fans, backface culling, and depth testing
// Program by Richard S. Wright Jr.

import javax.media.opengl.GL2;

public class Star
{
	// Define a constant for the value of PI
	static float GL_PI = 3.1415f;
	
	// Rotation amounts
	static float xRot = 0.0f;
	static float yRot = 0.0f;
	
	// Flags for effects
	static int MODE_SOLID = 0;
	static int MODE_LINE = 1;
	static int MODE_POINT = 2;
	
	static int iMode = MODE_SOLID;
	static boolean bEdgeFlag = true;
		
	///////////////////////////////////////////////////////////////////////////////
	// Reset flags as appropriate in response to menu selections
	public static void processMenu(int value)
	{
		switch(value)
		{
			case 1:
				iMode = MODE_SOLID;
				break;

			case 2:
				iMode = MODE_LINE;
				break;
				
			case 3:
				iMode = MODE_POINT;
				break;
				
			case 4:
				bEdgeFlag = true;
				break;
				
			case 5:
			default:
				bEdgeFlag = false;
				break;
		}		
	}
	
	// Setup the rendering state
	protected static void setupRC(GL2 gl2, int width, int height)
	{
		// Black background
		gl2.glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
		
		// Set drawing color to green
		gl2.glColor3f(0.0f, 1.0f, 0.0f);
	}
	
	// Called to draw scene
	protected static void renderScene(GL2 gl2, int w, int h)
	{	
		// Clear the window and the depth buffer
		gl2.glClear(GL2.GL_COLOR_BUFFER_BIT);

		// Draw back side as a polygon only, if flag is set
		if(iMode == MODE_LINE)
			gl2.glPolygonMode(GL2.GL_FRONT_AND_BACK, GL2.GL_LINE);
		
		if(iMode == MODE_POINT)
			gl2.glPolygonMode(GL2.GL_FRONT_AND_BACK, GL2.GL_POINT);
		
		if(iMode == MODE_SOLID)
			gl2.glPolygonMode(GL2.GL_FRONT_AND_BACK, GL2.GL_FILL);
		
		// Save matrix state and do the rotation
		gl2.glPushMatrix();
		gl2.glRotatef(xRot, 1.0f, 0.0f, 0.0f);
		gl2.glRotatef(yRot, 0.0f, 1.0f, 0.0f);
		
		// Begin the triangles
		gl2.glBegin(GL2.GL_TRIANGLES);
		
			gl2.glEdgeFlag(bEdgeFlag);
			gl2.glVertex2f(-20.0f, 0.0f);
			gl2.glEdgeFlag(true);
			gl2.glVertex2f(20.0f, 0.0f);
			gl2.glVertex2f(0.0f, 40.0f);
			
			gl2.glVertex2f(-20.0f, 0.0f);
			gl2.glVertex2f(-60.0f, -20.0f);
			gl2.glEdgeFlag(bEdgeFlag);
			gl2.glVertex2f(-20.0f, -40.0f);
			gl2.glEdgeFlag(true);
			
			gl2.glVertex2f(-20.0f, -40.0f);
			gl2.glVertex2f(0.0f, -80.0f);
			gl2.glEdgeFlag(bEdgeFlag);
			gl2.glVertex2f(20.0f, -40.0f);
			gl2.glEdgeFlag(true);
			
			gl2.glVertex2f(20.0f, -40.0f);
			gl2.glVertex2f(60.0f, -20.0f);
			gl2.glEdgeFlag(bEdgeFlag);
			gl2.glVertex2f(20.0f, 0.0f);
			gl2.glEdgeFlag(true);
			
			// Center square as two triangles
			gl2.glEdgeFlag(bEdgeFlag);
			gl2.glVertex2f(-20.0f, 0.0f);
			gl2.glVertex2f(-20.0f, -40.0f);
			gl2.glVertex2f(20.0f, 0.0f);
			
			gl2.glVertex2f(-20.0f, -40.0f);
			gl2.glVertex2f(20.0f, -40.0f);
			gl2.glVertex2f(20.0f, 0.0f);
			gl2.glEdgeFlag(true);
			
		// Done drawing Triangles
		gl2.glEnd();
		
		// Restore transformations
		gl2.glPopMatrix();
		
		// Flush drawing commands
		gl2.glFlush();
	}
	
	public static void changeSize(GL2 gl2, int w, int h)
	{
		float nRange = 100.0f;
		
		// Prevent a divide by zero
		if(h == 0)
			h = 1;
		
		// Set Viewport to window dimensions
		gl2.glViewport(0, 0, w, h);
		
		// Reset projection matrix stack
		gl2.glMatrixMode(GL2.GL_PROJECTION);
		gl2.glLoadIdentity();
		
		// Establish clipping volume (left, right, bottom, top, near, far)
		if(w <= h)
			gl2.glOrtho(-nRange, nRange, -nRange * h / w, nRange * h / w, -nRange, nRange);
		else
			gl2.glOrtho(-nRange * w / h, nRange * w / h, -nRange, nRange, -nRange, nRange);
		
		// Reset Model view matrix stack
		gl2.glMatrixMode(GL2.GL_MODELVIEW);
		gl2.glLoadIdentity();		
	}
}